﻿/* 
 * 源码己托管: https://git.oschina.net/dlgcy/dotnetcodes
 */
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace DLGCY.Utilities
{
    public class DataTableHelper
    {
        /// <summary>
        /// dlgcy:为给定的DataTable添加一行总计;
        /// </summary>
        /// <param name="dt">给定的Table</param>
        /// <param name="putTotalName">存放总计名称的列号</param>
        /// <param name="totalName">总计名称</param>
        /// <param name="startColumn">开始统计的列号</param>
        /// <returns>DataTable</returns>
        public static DataTable AddTotalRowToTable(DataTable dt, int putTotalName, string totalName, int startColumn)
        {
            if (null == dt || 0 == dt.Rows.Count)
            {
                return dt;
            }

            DataRow newRow = dt.NewRow();
            newRow[putTotalName] = totalName;

            foreach (DataRow row in dt.Rows)
            {
                for (int i = startColumn; i < row.ItemArray.Length; i++)
                {
                    if (string.IsNullOrEmpty(newRow[i].ToString()))
                    {
                        newRow[i] = 0;
                    }
                    if (!string.IsNullOrEmpty(row[i].ToString()))
                    {
                        try
                        {
                            newRow[i] = double.Parse(newRow[i].ToString()) + double.Parse(row[i].ToString());
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }
                }
            }

            dt.Rows.Add(newRow);
            return dt;
        }

        /// <summary>
        /// dlgcy:为给定的DataTable添加一行平均值;(依赖AddTotalRowToTable);
        /// </summary>
        /// <param name="dt">给定的Table</param>
        /// <param name="putAvgName">存放平均值名称的列号</param>
        /// <param name="avgName">平均值名称</param>
        /// <param name="startColumn">开始统计的列号</param>
        /// <param name="format">可选参数,指定平均值的格式;用于double的ToString()的参数,比如"F4"、"F5"等</param>
        /// <returns>DataTable</returns>
        public static DataTable AddAvgRowToTable(DataTable dt, int putAvgName, string avgName, int startColumn, string format = "F4")
        {
            if (null == dt || 0 == dt.Rows.Count)
            {
                return dt;
            }

            int num = dt.Rows.Count;
            dt = AddTotalRowToTable(dt, putAvgName, avgName, startColumn);

            DataRow row = dt.Rows[num];
            for (int i = startColumn; i < dt.Columns.Count; i++)
            {
                row[i] = Convert.ToDouble(double.Parse(row[i].ToString()) / num).ToString(format);
            }

            return dt;
        }

        /// <summary>
        /// dlgcy:使用Linq对给定的DataTable排序;
        /// </summary>  
        /// <param name="dt">数据表格</param>
        /// <param name="columnName">排序列</param>
        /// <param name="isNum">是否是数字列（是否要以数值排序）</param>
        /// <param name="isDesc">是否倒序排序</param>
        /// <returns>排序完成的DataTable</returns>      
        public static DataTable OrderDataTable(DataTable dt, string columnName, bool isNum, bool isDesc)
        {
            EnumerableRowCollection<DataRow> rows = from row in dt.AsEnumerable() select row;

            if (isDesc)
            {
                if (isNum)
                {
                    rows = rows.OrderByDescending(r => double.Parse(r[columnName].ToString()));
                }
                else
                {
                    rows = rows.OrderByDescending(r => r[columnName]);
                }
            }
            else
            {
                if (isNum)
                {
                    rows = rows.OrderBy(r => double.Parse(r[columnName].ToString()));
                }
                else
                {
                    rows = rows.OrderBy(r => r[columnName]);
                }
            }

            return dt = rows.CopyToDataTable();
        }

        /// <summary>
        /// 获取DataTable前几条数据
        /// </summary>
        /// <param name="topNum">前N条数据</param>
        /// <param name="dt">源DataTable</param>
        /// <returns>DataTable</returns>
        public static DataTable DtSelectTop(int topNum, DataTable dt)
        {
            if (dt.Rows.Count < topNum) return dt;

            DataTable newTable = dt.Clone();
            DataRow[] rows = dt.Select("1=1");
            for (int i = 0; i < topNum; i++)
            {
                newTable.ImportRow((DataRow)rows[i]);
            }
            return newTable;
        }

        /// <summary>
        /// dlgcy:获取DataTable的指定页;
        /// </summary>
        /// <param name="page">指定页</param>
        /// <param name="perPageNum">每页数据条数</param>
        /// <param name="dtOrigion">原始DataTable</param>
        /// <returns>指定页数据DataTable</returns>
        public static DataTable GetPagedDataTable(int page, int perPageNum, DataTable dtOrigion)
        {
            if (dtOrigion == null)
            {
                return null;
            }

            DataTable dt = dtOrigion.Clone();
            int totalDataCount = dtOrigion.Rows.Count;

            int start = perPageNum * (page - 1);
            if (totalDataCount > start)
            {
                int end = start + perPageNum;
                if (end > totalDataCount)
                {
                    end = totalDataCount;
                }

                DataRowCollection rows = dtOrigion.Rows;
                for (int i = start; i < end; i++)
                {
                    dt.ImportRow(rows[i]);
                }
            }

            return dt;
        }
    }
}
